package com.families.shiro;

import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;

@Configuration
public class ShiroConfig {
	//
	//配置拦截
	@Bean
	public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
		//设置securityManager
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		//不设置会自动寻找web工程下的login.jsp页面
		shiroFilterFactoryBean.setLoginUrl("/");
		//拦截器
		Map<String,String> map = new HashMap<>();
		//配置不会被拦截连接
		// ① authc:所有url都必须认证通过才可以访问; ② anon:所有url都都可以匿名访问`
		//map.put("/static/**", "anon");
		map.put("/css/**","anon");
		map.put("/js/**","anon");
		map.put("/music/**","anon");
		map.put("/image/*","anon");
		map.put("/templates/*", "anon");
		map.put("/templates/phone/*", "anon");
		map.put("/live2dw/*", "anon");
		map.put("/", "anon");
		map.put("/toSign**", "anon"); 
		map.put("/shiro/login", "anon");
		map.put("/shiro/signNameComparison*", "anon");
		map.put("/shiro/sign*", "anon");
		map.put("/login.html", "anon");
		map.put("/success.html", "anon");

		
		//配置退出过滤器
		map.put("/logout", "logout");
		// 过滤链定义，从上向下顺序执行，一般将 /**放在最为下边 :这是一个坑呢，一不小心代码就不好使了;
	    map.put("/**", "authc"); 
		//没有权限走的路径
		shiroFilterFactoryBean.setUnauthorizedUrl("403.jsp");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
		return shiroFilterFactoryBean;

	}
	@Bean
	public SecurityManager securityManager() {
		DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
		//设置realm
		securityManager.setRealm(myrealm());
		securityManager.setRememberMeManager(rememberMeManager());
		securityManager.setSessionManager(getDefaultWebSessionManager());
		return securityManager;

	}
	//身份认证realm(账号密码认证,权限等)
	@Bean
	public MyRealm myrealm() {
		// TODO Auto-generated method stub
		MyRealm myrealm = new MyRealm();
		myrealm.setCredentialsMatcher(hashedCredentialsMatcher());
		return myrealm;
	}
	//shiro生命周期
	@Bean(name = "lifecycleBeanPostProcessor")
	public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {

		return new LifecycleBeanPostProcessor();
	}
	//开启shiro注解
	@Bean
	public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
		daap.setProxyTargetClass(true);
		return daap;
	}

	@Bean
	public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() {
		AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
		aasa.setSecurityManager(securityManager());
		return aasa;
	}
	//凭证匹配器  密码加密时使用
	@Bean
	public HashedCredentialsMatcher hashedCredentialsMatcher() {
		HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
		hashedCredentialsMatcher.setHashAlgorithmName("MD5");//散列算法:MD2、MD5、SHA-1、SHA-256、SHA-384、SHA-512等。
		hashedCredentialsMatcher.setHashIterations(1);//散列的次数，默认1次， 设置两次相当于 md5(md5(""));
		hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
		return hashedCredentialsMatcher;
	}

	//配置sessionDao
	@Bean(name="sessionDAO")
	public MemorySessionDAO getMemorySessionDAO(){
		MemorySessionDAO sessionDAO = new MemorySessionDAO();
		return sessionDAO;
	}

	//shiro配置session管理器
	@Bean(name = "sessionManager")
	public DefaultWebSessionManager getDefaultWebSessionManager() {
		DefaultWebSessionManager defaultWebSessionManager=new DefaultWebSessionManager();
		defaultWebSessionManager.setGlobalSessionTimeout(60*60*1000);
		defaultWebSessionManager.setSessionDAO(getMemorySessionDAO());

		return defaultWebSessionManager;
	}

	@Bean
	public EnterpriseCacheSessionDAO enterCacheSessionDAO() {
		EnterpriseCacheSessionDAO enterCacheSessionDAO = new EnterpriseCacheSessionDAO();
		//添加缓存管理器
		//enterCacheSessionDAO.setCacheManager(ehCacheManager());
		//添加ehcache活跃缓存名称（必须和ehcache缓存名称一致）
		enterCacheSessionDAO.setActiveSessionsCacheName("shiro-activeSessionCache");
		return enterCacheSessionDAO;
	}

	@Bean
	public RememberMeManager rememberMeManager() {
		CookieRememberMeManager rememberMeManager = new CookieRememberMeManager();
		SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
		simpleCookie.setHttpOnly(true);        //设置RememberMe的cookie有效期为7天
		simpleCookie.setMaxAge(604800);
		rememberMeManager.setCookie(simpleCookie);      
		rememberMeManager.setCipherKey(Base64.decode("6ZmI6I2j3Y+R1aSn5BOlAA=="));
		return rememberMeManager;
	}


}
